package com.tc.controller;

import com.alibaba.fastjson.JSON;
import com.tc.config.GetHttpSessionConfig;
import com.tc.config.SpringUtils;
import com.tc.dto.SocketMessage;
import com.tc.messageDto.Message;
import com.tc.utils.TransformHashCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@ServerEndpoint(value = "/message/socket",configurator = GetHttpSessionConfig.class)
@Component
public class WebSocketController {
    private static RedisTemplate redisTemplate;
    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate){
        this.redisTemplate = redisTemplate;
    }
    //使用线程安全的map集合存储已连接的用户
    private static final Map<String,Session> map=new ConcurrentHashMap<>();
    //储存该对象的识别信息
    private String userId;

    //建立连接后被调用
    @OnOpen
    public void onOpen(Session session, EndpointConfig config){//获取配置对象
        //从配置对象中获取用户信息
        Object o= config.getUserProperties().get(HttpSession.class.getName());
        //先保存个人信息
        setUserId((String) o);
        //然后进行获取用户id,将session进行保存,这里记录的是已经创建连接的用户
        map.put(getUserId(),session);

    }

    //接收参数时触发
    @OnMessage
    public void onMessage(String message) throws IOException {
        //首先把JSON格式转为对象
        SocketMessage socketMessage=JSON.parseObject(message,SocketMessage.class);
        //把消息推送给用户,首先得获取目标用户的session,去已连接用户中寻找
        if(map.get(String.valueOf(socketMessage.getToUserId()))==null){
            //如果没有说明用户不在线,目前不能发送,则所以需要提示当前用户
            Session session=map.get(getUserId());
            String sendMsg=JSON.toJSONString(new SocketMessage(404,
                                                                Integer.valueOf(getUserId()),
                                                                "找不到用户"));
            session.getBasicRemote().sendText(sendMsg);
            log.info("我被触发了");
        }else{
            //此时说明该用户在线,可以发送,首先根据id获取对方session
            Session session=map.get(String.valueOf(socketMessage.getToUserId()));
            //判断是否为更新操作
            if(socketMessage.getCode()!=null && socketMessage.getCode()==100){//此时说明是更新操作,得提醒用户
                session.getBasicRemote().sendText(JSON.toJSONString(
                        new SocketMessage(100,
                                          socketMessage.getToUserId(),
                                          "更新聊天信息")
                ));
            }else{
                String sendMsg=JSON.toJSONString(new SocketMessage(200,
                        Integer.valueOf(getUserId()),
                        socketMessage.getData()));
                session.getBasicRemote().sendText(sendMsg);
                //获取会话id
                Integer sessionId= TransformHashCode.chatSessionId(Integer.valueOf(getUserId()), socketMessage.getToUserId());
                //并存入redis,从右侧进入即可保证顺序
                redisTemplate.opsForList().rightPush("sessionId_"+sessionId,new Message(socketMessage.getData(),getUserId()));
                log.info(message);
            }

        }


    }

    //关闭连接时触发
    @OnClose
    public void onClose(Session session){
        //在在线集合中删除该用户的session
        map.remove(getUserId());
    }

    public void setUserId(String userId){
        this.userId=userId;
    }
    public String getUserId(){
        return this.userId;
    }
}
